package org.javahispano.javacup.visores;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.DecimalFormat;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import org.javahispano.javacup.gui.principal.Principal;
import org.javahispano.javacup.modelo.Constantes;
import org.javahispano.javacup.modelo.PartidoInterfaz;
import org.javahispano.javacup.modelo.Posicion;
import org.javahispano.javacup.modelo.TacticaDetalle;
import org.javahispano.javacup.modelo.ValidaTactica;

/**
Visor Basico, extiende de JFrame
 */
public class VisorBasico extends javax.swing.JFrame {

    Principal principal = null;
    /**variable estatica para setear si se dibujaran los jugadores o las esferas*/
    public static boolean dibujaJugadores = true;
    /**Variable estatica para setear si se usara doble buffer*/
    public static boolean dobleBuffer = true;
    /**Variable estatica para setear si se mostraran los numeros de los jugadores*/
    public static boolean numeros = false;
    Image imgCampo, imgArcoSup, imgArcoInf, imgBalon, balon, balonSombra, sombra;
    Image imgLocal[] = new Image[7];
    Image imgVisita[] = new Image[7];
    Image imgLoc, imgVis;
    int sx = 327;
    int sy = 504;
    int sx2 = sx / 2;
    int sy2 = sy / 2;
    int dx = 40;
    int dy = 47;
    int[] posArcSup = transformVisorBasico(new Posicion(-Constantes.LARGO_ARCO / 2, -Constantes.LARGO_CAMPO_JUEGO / 2 - 2 + 0.2));
    int[] posArcInf = transformVisorBasico(new Posicion(-Constantes.LARGO_ARCO / 2, Constantes.LARGO_CAMPO_JUEGO / 2 + 0.3));

    private int[] transformVisorBasico(Posicion p) {
        int x = dx + sx2 + (int) (sx * p.getX() / Constantes.ANCHO_CAMPO_JUEGO);
        int y = dy + sy2 + (int) (sy * p.getY() / Constantes.LARGO_CAMPO_JUEGO);
        return new int[]{x, y};
    }

    private int[] size(Posicion p) {
        int x = (int) (sx * p.getX() / Constantes.ANCHO_CAMPO_JUEGO);
        int y = (int) (sy * p.getY() / Constantes.LARGO_CAMPO_JUEGO);
        return new int[]{x, y};
    }

    private void loadImages() throws IOException {
        boolean uniformeAlternativoLocal = ValidaTactica.usarUniformeAlternativo(p.getDetalleLocal(), p.getDetalleVisita());
        int polera = new Color(255, 255, 0).getRGB();
        int pantalon = new Color(255, 0, 255).getRGB();
        int calcetas = new Color(0, 0, 255).getRGB();
        int franja = new Color(0, 255, 0).getRGB();
        int pelo = new Color(255, 255, 255).getRGB();

        int[] d0 = size(new Posicion(Constantes.LARGO_ARCO, 2));
        imgCampo = ImageIO.read(getClass().getResource("/imagenes/cancha.png")).getScaledInstance(408, 600, Image.SCALE_SMOOTH);
        imgArcoInf = ImageIO.read(getClass().getResource("/imagenes/arco_inferior.png")).getScaledInstance(d0[0], d0[1], Image.SCALE_SMOOTH);
        imgArcoSup = ImageIO.read(getClass().getResource("/imagenes/arco_superior.png")).getScaledInstance(d0[0], d0[1], Image.SCALE_SMOOTH);
        balon = ImageIO.read(getClass().getResource("/imagenes/minibalon.png"));
        balonSombra = ImageIO.read(getClass().getResource("/imagenes/balon/sombra.png")).getScaledInstance(5, 5, Image.SCALE_SMOOTH);
        sombra = ImageIO.read(getClass().getResource("/imagenes/sombra.png")).getScaledInstance(13, 13, Image.SCALE_SMOOTH);
        int el = p.getDetalleLocal().getEstilo().getNumero();
        int ev = p.getDetalleVisita().getEstilo().getNumero();
        for (int i = 0; i < 7; i++) {
            imgLocal[i] = ImageIO.read(getClass().getResource("/imagenes/jugador/" + el + "" + i + ".png"));
            imgVisita[i] = ImageIO.read(getClass().getResource("/imagenes/jugador/" + ev + "" + i + ".png"));
        }
        TacticaDetalle impl = p.getDetalleLocal();
        int upolera;
        int upantalon;
        int ucalcetas;
        int ufranja;
        if (!uniformeAlternativoLocal) {
            ucalcetas = new Color(impl.getColorCalcetas().getRed(), impl.getColorCalcetas().getGreen(), impl.getColorCalcetas().getBlue()).getRGB();
            upantalon = new Color(impl.getColorPantalon().getRed(), impl.getColorPantalon().getGreen(), impl.getColorPantalon().getBlue()).getRGB();
            upolera = new Color(impl.getColorCamiseta().getRed(), impl.getColorCamiseta().getGreen(), impl.getColorCamiseta().getBlue()).getRGB();
            ufranja = new Color(impl.getColorFranja().getRed(), impl.getColorFranja().getGreen(), impl.getColorFranja().getBlue()).getRGB();
        } else {
            ucalcetas = new Color(impl.getColorCalcetas2().getRed(), impl.getColorCalcetas2().getGreen(), impl.getColorCalcetas2().getBlue()).getRGB();
            upantalon = new Color(impl.getColorPantalon2().getRed(), impl.getColorPantalon2().getGreen(), impl.getColorPantalon2().getBlue()).getRGB();
            upolera = new Color(impl.getColorCamiseta2().getRed(), impl.getColorCamiseta2().getGreen(), impl.getColorCamiseta2().getBlue()).getRGB();
            ufranja = new Color(impl.getColorFranja2().getRed(), impl.getColorFranja2().getGreen(), impl.getColorFranja2().getBlue()).getRGB();
        }
        int upelo = Color.black.getRGB();
        {
            BufferedImage buf = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
            Graphics gr = buf.getGraphics();
            gr.setColor(impl.getColorCamiseta());
            gr.fillArc(4, 4, 11, 11, 0, 180);
            gr.setColor(impl.getColorPantalon());
            gr.fillArc(4, 4, 11, 11, 180, 180);
            gr.setColor(impl.getColorFranja());
            gr.drawOval(2, 2, 15, 15);
            imgLoc = buf.getScaledInstance(20, 20, Image.SCALE_SMOOTH);
        }
        for (int k = 0; k < 7; k++) {
            BufferedImage buf = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
            buf.getGraphics().drawImage(imgLocal[k], 0, 0, null);
            for (int i = 0; i < 20; i++) {
                for (int j = 0; j < 20; j++) {
                    int color = buf.getRGB(i, j);
                    if (color == polera) {
                        buf.setRGB(i, j, upolera);
                    } else if (color == pantalon) {
                        buf.setRGB(i, j, upantalon);
                    } else if (color == calcetas) {
                        buf.setRGB(i, j, ucalcetas);
                    } else if (color == franja) {
                        buf.setRGB(i, j, ufranja);
                    } else if (color == pelo) {
                        buf.setRGB(i, j, upelo);
                    }
                }
            }
            imgLocal[k] = buf.getScaledInstance(20, 20, Image.SCALE_SMOOTH);
        }

        impl = p.getDetalleVisita();

        upolera = new Color(impl.getColorCamiseta().getRed(), impl.getColorCamiseta().getGreen(), impl.getColorCamiseta().getBlue()).getRGB();
        upantalon = new Color(impl.getColorPantalon().getRed(), impl.getColorPantalon().getGreen(), impl.getColorPantalon().getBlue()).getRGB();
        ucalcetas = new Color(impl.getColorCalcetas().getRed(), impl.getColorCalcetas().getGreen(), impl.getColorCalcetas().getBlue()).getRGB();
        ufranja = new Color(impl.getColorFranja().getRed(), impl.getColorFranja().getGreen(), impl.getColorFranja().getBlue()).getRGB();
        {
            BufferedImage buf = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
            Graphics gr = buf.getGraphics();
            gr.setColor(impl.getColorCamiseta());
            gr.fillArc(4, 4, 11, 11, 0, 180);
            gr.setColor(impl.getColorPantalon());
            gr.fillArc(4, 4, 11, 11, 180, 180);
            gr.setColor(impl.getColorFranja());
            gr.drawOval(2, 2, 15, 15);
            imgVis = buf.getScaledInstance(20, 20, Image.SCALE_SMOOTH);
        }
        for (int k = 0; k < 7; k++) {
            BufferedImage buf = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
            buf.getGraphics().drawImage(imgVisita[k], 0, 0, null);
            for (int i = 0; i < 20; i++) {
                for (int j = 0; j < 20; j++) {
                    int color = buf.getRGB(i, j);
                    if (color == polera) {
                        buf.setRGB(i, j, upolera);
                    } else if (color == pantalon) {
                        buf.setRGB(i, j, upantalon);
                    } else if (color == calcetas) {
                        buf.setRGB(i, j, ucalcetas);
                    } else if (color == franja) {
                        buf.setRGB(i, j, ufranja);
                    } else if (color == pelo) {
                        buf.setRGB(i, j, upelo);
                    }
                }
            }
            imgVisita[k] = buf.getScaledInstance(13, 13, Image.SCALE_SMOOTH);
        }
        for (int i = 0; i < 7; i++) {
            imgLocal[i] = imgLocal[i].getScaledInstance(13, 13, Image.SCALE_SMOOTH);
            imgVisita[i] = imgVisita[i].getScaledInstance(13, 13, Image.SCALE_SMOOTH);
        }
    }
    PartidoInterfaz p;
    BufferedImage bimg = new BufferedImage(408, 600, BufferedImage.TYPE_INT_ARGB);
    Posicion panterior[][] = new Posicion[2][11];
    Posicion[][] pos = new Posicion[2][11];
    Font f = new Font("arial", 0, 10);
    DecimalFormat df = new DecimalFormat("##.##");

    @Override
    public void paint(Graphics g) {
        Graphics2D gr;

        if (dobleBuffer) {
            gr = (Graphics2D) bimg.getGraphics();
        } else {
            gr = (Graphics2D) g;
        }
        gr.setFont(f);
        double altura = p.getAlturaBalon();
        gr.drawImage(imgCampo, 0, 0, null);
        int pp[], pb[];

        if (!dibujaJugadores) {
            for (int i = 0; i < 11; i++) {
                pp = transformVisorBasico(pos[0][i]);
                gr.drawImage(imgLoc, pp[0] - 10, pp[1] - 10, null);
                if (numeros) {
                    gr.setColor(Color.yellow);
                    gr.drawString("" + p.getDetalleLocal().getJugadores()[i].getNumero(), pp[0] - 2, pp[1] + 18);
                }
                pp = transformVisorBasico(pos[1][i]);
                gr.drawImage(imgVis, pp[0] - 10, pp[1] - 10, null);
                if (numeros) {
                    gr.setColor(Color.yellow);
                    gr.drawString("" + p.getDetalleVisita().getJugadores()[i].getNumero(), pp[0] - 2, pp[1] - 10);
                }
            }
        }
        pb = transformVisorBasico(p.getPosVisibleBalon());
        gr.drawImage(balonSombra, pb[0] + (int) (altura * 2d), pb[1] + (int) (altura * 2d), null);
        if (altura <= 2.9) {
            gr.drawImage(balon, pb[0] - 2, pb[1] - 2, null);
        }
        if (dibujaJugadores) {
            for (int i = 0; i < 11; i++) {
                pp = transformVisorBasico(pos[0][i]);
                gr.drawImage(sombra, pp[0], pp[1], null);
                pp = transformVisorBasico(pos[1][i]);
                gr.drawImage(sombra, pp[0], pp[1], null);
            }
            int it;
            for (int i = 0; i < 11; i++) {
                pp = transformVisorBasico(pos[0][i]);
                gr.translate(pp[0], pp[1]);
                gr.rotate(ang[0][i]);
                it = iter[0][i];
                if (it > 6) {
                    it = 13 - it;
                }
                gr.drawImage(imgLocal[it], - 6, - 6, null);
                gr.rotate(-ang[0][i]);
                if (numeros) {
                    gr.setColor(Color.yellow);
                    gr.drawString("" + p.getDetalleLocal().getJugadores()[i].getNumero(), -2, 18);
                }
                gr.translate(-pp[0], -pp[1]);
                pp = transformVisorBasico(pos[1][i]);
                gr.translate(pp[0], pp[1]);
                gr.rotate(ang[1][i]);
                it = iter[1][i];
                if (it > 6) {
                    it = 13 - it;
                }
                gr.drawImage(imgVisita[it], - 6, - 6, null);
                gr.rotate(-ang[1][i]);
                if (numeros) {
                    gr.setColor(Color.yellow);
                    gr.drawString("" + p.getDetalleVisita().getJugadores()[i].getNumero(), -2, -10);
                }
                gr.translate(-pp[0], -pp[1]);
            }
        }
        gr.drawImage(imgArcoSup, posArcSup[0], posArcSup[1], null);
        gr.drawImage(imgArcoInf, posArcInf[0], posArcInf[1], null);
        if (p.getAlturaBalon() > 2.9) {
            gr.drawImage(balon, pb[0] - 2, pb[1] - 2, null);
        }
        gr.setColor(Color.yellow);
        String time = "0";
        int sec = p.getIteracion() * Constantes.DELAY / 1000;
        time = time + sec / 60 + ":";
        sec = sec % 60;
        if (sec < 10) {
            time = time + "0";
        }
        time = time + sec;
        gr.drawString(time, 30, 585);
        time = p.getGolesLocal() + " - " + p.getGolesVisita();
        gr.drawString(time, 195, 585);
        time = df.format(100d * p.getPosecionBalonLocal()) + "% - " + df.format(100d * (1d - p.getPosecionBalonLocal())) + "%";
        gr.drawString(time, 300, 585);
        if (dobleBuffer) {
            g.drawImage(bimg, 0, 0, null);
        }
    }
    final Timer timer;
    double[][] ang = new double[2][11];
    int[][] iter = new int[2][11];

    public VisorBasico(PartidoInterfaz partido, Principal principal) throws IOException {
        this.principal = principal;
        p = partido;
        loadImages();
        initComponents();
        setSize(408, 600);
        int delay = 920 / Constantes.FPS;
        final VisorBasico este = this;
        try {
            p.iterar();
        } catch (Exception e) {
        }
        for (int i = 0; i < 11; i++) {
            panterior[0][i] = new Posicion();
            panterior[1][i] = new Posicion();
        }
        pos = p.getPosiciones();
        timer = new Timer(delay, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (p.getIteracion() < Constantes.ITERACIONES) {
                    try {
                        for (int i = 0; i < 11; i++) {
                            panterior[0][i] = pos[0][i];
                            panterior[1][i] = pos[1][i];
                        }
                        p.iterar();
                        pos = p.getPosiciones();
                        for (int i = 0; i < 11; i++) {
                            if (!panterior[0][i].equals(pos[0][i])) {
                                ang[0][i] = panterior[0][i].angulo(pos[0][i]) + Math.PI / 2;
                                iter[0][i] = (iter[0][i] + 1) % 14;
                            } else {
                                iter[0][i] = 3;
                            }
                            if (!panterior[1][i].equals(pos[1][i])) {
                                ang[1][i] = panterior[1][i].angulo(pos[1][i]) + Math.PI / 2;
                                iter[1][i] = (iter[1][i] + 1) % 14;
                            } else {
                                iter[1][i] = 3;
                            }
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();

                    }
                    este.repaint();
                }
            }
        });
        timer.start();
        setLocationRelativeTo(null);
        setVisible(true);
        if (principal != null) {
            principal.setVisible(false);
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        getContentPane().setLayout(null);

        pack();
    }// </editor-fold>//GEN-END:initComponents
    JFileChooser jfc = new JFileChooser();

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        timer.stop();
        dispose();
        if (p.fueGrabado()) {
            if (JOptionPane.showConfirmDialog(principal, "Desea guardar el partido?", "Guardar Partido", JOptionPane.YES_NO_OPTION) == 0) {
                if (jfc.showSaveDialog(principal) == JFileChooser.APPROVE_OPTION) {
                    try {
                        p.getPartidoGuardado().save(jfc.getSelectedFile());
                        if (principal != null) {
                            principal.addGuardadoLocal(jfc.getSelectedFile());
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
        if (principal == null) {
            System.exit(0);
        } else {
            principal.setVisible(true);
        }
    }//GEN-LAST:event_formWindowClosing

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
